package pay;

import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class StringUtil {



    /**
     * 对一个客户端上传的字符串进行规范化，去掉影响日志格式的字符。用于处理客户端上传的设备ID、机型等等
     * @param str
     * @return
     */
    public static String normalize(String str) {
        StringBuilder sb = new StringBuilder();
        int len = str.length();
        for (int i = 0; i < len; i++) {
            char ch = str.charAt(i);
            if (ch == '[' || ch == ']') {
                // 中括号日志用到，替换为空格
                sb.append(' ');
            } else if (ch >= 0x20 && ch <= 0x7E) {
                // ASCII字符，包括符号、字母和数字
                sb.append(ch);
            } else {
                // 其他字符替换为空格
                sb.append(' ');
            }
        }
        return sb.toString();
    }

    /**
     * 把收据字符串变成一行，方便打日志。
     * @param receipt
     * @return
     */
    public static String makeSingleLine(String receipt) {
        try {
            BufferedReader br = new BufferedReader(new StringReader(receipt));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        } catch (Exception e) {
            return receipt;
        }
    }

    protected static DecimalFormat longIntegerFormat = new DecimalFormat("###,###,###,###,###");
    private static final char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    /**
     * 计算两个字符串的相似度
     * @param str1
     * @param str2
     * @return 从0-1的相似度评价，1表示完全相等。
     */
    public static float compSimilarity(String str1, String str2){
        //计算两个字符串的长度。
        int len1 = str1.length();
        int len2 = str2.length();
        //建立上面说的数组，比字符长度大一个空间
        int[][] dif = new int[len1 + 1][len2 + 1];
        //赋初值，步骤B。
        for (int a = 0; a <= len1; a++) {
            dif[a][0] = a;
        }
        for (int a = 0; a <= len2; a++) {
            dif[0][a] = a;
        }
        //计算两个字符是否一样，计算左上的值
        int temp;
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
                    temp = 0;
                } else {
                    temp = 1;
                }
                //取三个值中最小的
                dif[i][j] = min(dif[i - 1][j - 1] + temp, dif[i][j - 1] + 1,
                        dif[i - 1][j] + 1);
            }
        }
        //计算相似度
        float similarity =1 - (float) dif[len1][len2] / Math.max(str1.length(), str2.length());
        return similarity;
    }

    //得到最小值
    private static int min(int... is) {
        int min = Integer.MAX_VALUE;
        for (int i : is) {
            if (min > i) {
                min = i;
            }
        }
        return min;
    }

    /**
     * 转换字符串到UTF格式。
     */
    public static byte[] toUTF(String s){
        try{
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            DataOutputStream dos = new DataOutputStream(bos);
            dos.writeUTF(s);
            dos.close();
            return bos.toByteArray();
        }catch(Exception e){
            return new byte[0];
        }
    }

    /**
     * 把一个字符串分成用指定字符隔开的多个字符串.
     * @param s 原始字符串
     * @param ch 分隔字符
     * @return 分割后的数组
     */
    public static String[] splitString(String s, char ch) {
        int startIndex = 0;
        int endIndex = 0;
        List<String> vs = new ArrayList<String>();
        while (true) {
            endIndex = s.indexOf(ch, startIndex);
            if (endIndex == -1) {
                String val = s.substring(startIndex);
                if (val.length() > 0) {
                    vs.add(val);
                }
                break;
            } else {
                String val = s.substring(startIndex, endIndex);
                if (val.length() > 0) {
                    vs.add(val);
                }
                startIndex = endIndex + 1;
            }
        }
        String[] strs = new String[vs.size()];
        vs.toArray(strs);
        return strs;
    }

    public static String[] splitString(String s, String tag) {
        int startIndex = 0;
        int endIndex = 0;
        int tagLen = tag.length();
        List<String> vs = new ArrayList<String>();
        while (true) {
            endIndex = s.indexOf(tag, startIndex);
            if (endIndex == -1) {
                String val = s.substring(startIndex);
                if (val.length() > 0) {
                    vs.add(val);
                }
                break;
            } else {
                String val = s.substring(startIndex, endIndex);
                if (val.length() > 0) {
                    vs.add(val);
                }
                startIndex = endIndex + tagLen;
            }
        }
        String[] strs = new String[vs.size()];
        vs.toArray(strs);
        return strs;
    }

    /** 按照空格或tab为间隔符，并且忽视期间所有空格或tab */
    public static String[] splitString(String s) {
        int startIndex = 0;
        int endIndex = 0;
        s = s.replace('\t', ' ');
        List<String> vs = new ArrayList<String>();
        while (true) {
            endIndex = s.indexOf(' ', startIndex);
            if (endIndex == -1) {
                vs.add(s.substring(startIndex));
                break;
            } else {
                vs.add(s.substring(startIndex, endIndex));
                startIndex = endIndex + 1;
                for (int i=startIndex; i<s.length(); i++) {
                    if (s.charAt(i) != ' ') {
                        startIndex = i;
                        break;
                    }
                }
            }
        }
        String[] strs = new String[vs.size()];
        vs.toArray(strs);
        return strs;
    }

    /** 非正则表达式的替换，速度会快 **/
    public static String replaceAll(String str, String oldStr, String newStr) {
        int index = str.indexOf(oldStr);
        if (index >= 0) {
            int oldLen = oldStr.length();
            int lastIndex = 0;
            StringBuilder sb = new StringBuilder();
            for (;index < str.length() ; ) {
                String s = str.substring(lastIndex, index);
                sb.append(s);
                sb.append(newStr);
                lastIndex = index + oldLen;
                index = str.indexOf(oldStr, lastIndex);
                if (index < 0) {
                    break;
                }
            }
            String s = str.substring(lastIndex);
            sb.append(s);
            return sb.toString();
        }
        return str;
    }

    public static String longArrayToString(long[] arr, char delimiter) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            if (i > 0) {
                sb.append(delimiter);
            }
            sb.append(arr[i]);
        }
        return sb.toString();
    }

    public static long[] stringToLongArray(String str, char delimiter) {
        if (str == null || str.length() == 0) {
            return null;
        }
        String[] tmp = splitString(str, delimiter);
        long[] ret = new long[tmp.length];
        for (int i = 0; i < ret.length; i++) {
            ret[i] = Long.parseLong(tmp[i]);
        }
        return ret;
    }


}
